package com.xhj.mybatis.reflection.property;

import java.util.Iterator;

/**
 * PropertyTokenizer
 *
 * @author XJks
 * @description PropertyTokenizer 类用于将类似 "user.address[0].street" 这样的属性表达式进行分割和遍历。
 * <p>
 * TODO:
 *  主要作用:根据属性名称与路径，把字符串变成可导航的token。
 *  例子:
 *      把 "user.addressList[0].street" 解析为一段段 token：
 *          1.name=user，index=null
 *          2.name=addressList，index=0
 *          3.name=street，index=null
 *          4.提供 getChildren() 继续向后遍历。
 *          5.作用：让 点号/索引 混合路径能被一段段地“走过去”。
 */
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
    /**
     * 当前属性名（如 user.address.street）
     */
    private String name;

    /**
     * 带索引的属性名（如 address[0]）
     */
    private final String indexedName;

    /**
     * 属性的索引（如 0），如果没有索引则为 null
     */
    private String index;

    /**
     * 剩余的子属性（如 address[0].street 的 street 部分），如果没有则为 null
     */
    private final String children;

    /**
     * 构造方法，接收完整的属性表达式
     *
     * @param fullname 完整的属性表达式
     */
    public PropertyTokenizer(String fullname) {
        // 查找第一个点号，分割属性和子属性
        int delim = fullname.indexOf('.');
        if (delim > -1) {
            // 有点号，name 为点号前内容，children 为点号后内容
            name = fullname.substring(0, delim);
            children = fullname.substring(delim + 1);
        } else {
            // 没有点号，name 为全部内容，children 设为 null
            name = fullname;
            children = null;
        }
        // indexedName 记录原始 name（可能带索引）
        indexedName = name;
        // 查找中括号，判断是否有索引
        delim = name.indexOf('[');
        if (delim > -1) {
            // 有索引，index 取中括号内内容
            index = name.substring(delim + 1, name.length() - 1);
            // name 只保留中括号前内容
            name = name.substring(0, delim);
        }
    }

    /**
     * 获取当前属性名
     *
     * @return 当前属性名
     */
    public String getName() {
        return name;
    }

    /**
     * 获取索引值
     *
     * @return 索引值
     */
    public String getIndex() {
        return index;
    }

    /**
     * 获取带索引的属性名
     *
     * @return 带索引的属性名
     */
    public String getIndexedName() {
        return indexedName;
    }

    /**
     * 获取剩余的子属性表达式
     *
     * @return 子属性表达式
     */
    public String getChildren() {
        return children;
    }

    /**
     * 判断是否还有子属性（即 children 是否为 null）
     *
     * @return 如果有子属性返回 true，否则返回 false
     */
    @Override
    public boolean hasNext() {
        return children != null;
    }

    /**
     * 获取下一个 PropertyTokenizer，用于遍历子属性
     *
     * @return 下一个 PropertyTokenizer 实例
     */
    @Override
    public PropertyTokenizer next() {
        return new PropertyTokenizer(children);
    }

    /**
     * 不支持 remove 操作，直接抛出异常
     */
    @Override
    public void remove() {
        throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
    }
}
